#include <WIFI/my_wifi.h>

DNSServer DNS_ConnectWiFi;
bool  _is_connecting=false;
WiFiMulti Wifimtu;

IPAddress local_ip(192,168,4,1);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);

JsonDocument saved_aps;

wl_status_t wifi_status;

uint8_t WiFi_Init()
{
  uint8_t connect_state=WL_CONNECT_FAILED;
  WiFi.mode(WIFI_AP_STA);
  connect_state=ConnectWiFi();
  return connect_state;
}

bool WiFiConnectionDector()
{
  wifi_status=WiFi.status();
  if(wifi_status!=WL_CONNECTED&&_is_connecting==false)//huaweispace206
  {
    digitalWrite(WIFI_EN,HIGH);
    _is_connecting=true;
    WiFi.disconnect();
    Serial.println("error:wifi not connected,opening AP");
    if(WiFi.softAP("ESP32_WiFiConfig",NULL)){ 
      Serial.println("");              // 通过串口监视器输出信息
      Serial.print("接入点名字:");    
      Serial.println("ESP32_WiFiConfig");            // 告知用户建立的接入点WiFi名
      Serial.print("网络IP:");
      Serial.println(WiFi.softAPIP());     //打印ip地址
    }else{
      //若没有开启成功
      Serial.println("开启失败");
    }
    if(DNS_ConnectWiFi.start(53,"*",WiFi.softAPIP())==true)
    {
      Serial.println("已开启强制门户认证");
    }
  }
  else if(wifi_status==WL_CONNECTED&&_is_connecting==true)
  {
    digitalWrite(WIFI_EN,LOW);
    _is_connecting=false;
    DNS_ConnectWiFi.stop();
  }
  if(wifi_status!=WL_CONNECTED)
  {
    DNS_ConnectWiFi.processNextRequest();
  }
  return _is_connecting;
}

/*利用Wifimtu自动连接信号最好的wifi*/
uint8_t ConnectWiFi()
{
  uint8_t connect_state=WL_CONNECT_FAILED;
  static uint8_t wifi_connect_retry_times=3;

  deserializeJson(saved_aps,readFile("/saved_aps/networks.json"));
  for(uint8_t i=0;i<saved_aps["ap"].size();i++)
  {
    Wifimtu.addAP(saved_aps["ap"][i]["ssid"].as<String>().c_str(),saved_aps["ap"][i]["password"].as<String>().c_str());
    Serial.println("ap"+(String)std::to_string(i).c_str()+":");
    Serial.println("ssid:"+saved_aps["ap"][i]["ssid"].as<String>());
    Serial.println("password:"+saved_aps["ap"][i]["password"].as<String>());
    Serial.println();
  }
  if((connect_state=Wifimtu.run(1500))!=WL_CONNECTED&&_is_connecting==false)//huaweispace206
  {
    WiFi.disconnect();
    //WiFi.softAPConfig(local_ip,gateway,subnet);
    for(;wifi_connect_retry_times>0;)
    {
      Serial.printf("error:wifi not connected,retry:%d\n",wifi_connect_retry_times);
      if((connect_state=Wifimtu.run(1500))!=WL_CONNECTED)
      {
        WiFi.disconnect();
        wifi_connect_retry_times-=1;
      }
      else
      {
        Serial.println("connected");
        Serial.println("server ip:"+WiFi.localIP().toString());
        Serial.println();
        break;
      }
    }
    if(connect_state!=WL_CONNECTED)
    {
      _is_connecting=true;
      Serial.println("error:wifi not connected,opening AP");
      WiFi_OpenAPWithDNS();
    }

  }
  else
  {
    Serial.println("connected");
    Serial.println("server ip:"+WiFi.localIP().toString());
    Serial.println();
  }
  
  return connect_state;
}

/*不使用Wifimtu，指定连接的网络名并提供密码*/
uint8_t ConnectWiFi(String ssid,String password)
{
  //Wifimtu.addAP(ssid.c_str(),password.c_str());
  WiFi.disconnect();
  Serial.print("Waiting for WiFi to connect...");
  uint8_t Wifimtu_Status;
  //Wifimtu_Status=Wifimtu.run(1500);
  WiFi.begin(ssid,password);

  for(uint8_t i=0;i<15&&(Wifimtu_Status != WL_CONNECTED && Wifimtu_Status != WL_NO_SSID_AVAIL && Wifimtu_Status != WL_CONNECT_FAILED);i++)
  {
    delay(1000); 
    Serial.print('.');
    Wifimtu_Status=WiFi.status();
  }

  Serial.println();

  switch(Wifimtu_Status) {
    case WL_CONNECTED:
        log_i("[WIFI] Connecting done.");
        log_d("[WIFI] SSID: %s", WiFi.SSID().c_str());
        log_d("[WIFI] IP: %s", WiFi.localIP().toString().c_str());
        log_d("[WIFI] MAC: %s", WiFi.BSSIDstr().c_str());
        log_d("[WIFI] Channel: %d", WiFi.channel());
        break;
    case WL_NO_SSID_AVAIL:
        log_e("[WIFI] Connecting Failed AP not found.");
        break;
    case WL_CONNECT_FAILED:
        log_e("[WIFI] Connecting Failed.");
        break;
    default:
        log_e("[WIFI] Connecting Failed (%d).", Wifimtu_Status);
        break;
  }

  return Wifimtu_Status;
}

void WiFi_OpenAPWithDNS()
{
  WiFi.disconnect();
  if(WiFi.softAP("ESP32_WiFiConfig",NULL)){
  Serial.println("");              // 通过串口监视器输出信息
  Serial.print("接入点名字:");    
  Serial.println("ESP32_WiFiConfig");            // 告知用户建立的接入点WiFi名
  Serial.print("网络IP:");
  Serial.println(WiFi.softAPIP());     //打印ip地址
  }else{
    //若没有开启成功
    Serial.println("开启失败");
  }
  if(DNS_ConnectWiFi.start(53,"*",WiFi.softAPIP())==true)
  {
    Serial.println("已开启强制门户认证");
  }
}

JsonDocument* Wifi_GetSavedAps()
{
    return &saved_aps;
}

uint8_t wifi_return_status()
{
  return wifi_status;
}
